/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.fedoraaccess.resourceIndex;

import cz.mzk.kramerius.commons.Dom4jUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.dom4j.Document;

/**
 *
 * @author Martin Řehánek <rehan at mzk.cz>
 */
public class ResourceIndexReader {

    private static final Logger logger = Logger.getLogger(ResourceIndexReader.class.getName());
    private static final String FEDORA_PREFIX = "info:fedora/";
    private final String resouceIndexUrl;
    private final RdfParser rdfParser = new RdfParser();

    public ResourceIndexReader(String resourceIndexUrl) {
        this.resouceIndexUrl = resourceIndexUrl;
    }

    public List<String> getSubjects(String object, String predicate) {
        try {
            String query = buildSubjectQuery(object, predicate);
            logger.log(Level.FINE, query);
            String response = procesRequest(query);
            logger.log(Level.FINEST, response);
            Document responseDoc = Dom4jUtils.loadDocument(response, false);
            return rdfParser.parseSubjects(responseDoc);
        } catch (Exception ex) {
            Logger.getLogger(ResourceIndexReader.class.getName()).log(Level.SEVERE, null, ex);
            return Collections.<String>emptyList();
        }
    }

    private String buildSubjectQuery(String object, String predicate) {
        return "* "
                + predicate + " "
                + "<" + FEDORA_PREFIX + object + ">";
    }

    private String procesRequest(String query) throws IOException {
        List<NameValuePair> params = buildParams(query);
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
        HttpPost post = new HttpPost(resouceIndexUrl);
        post.setEntity(entity);
        DefaultHttpClient httpclient = new DefaultHttpClient();
        HttpResponse response = httpclient.execute(post);
        InputStream responseStream = response.getEntity().getContent();
        return streamToString(responseStream);
    }

    private List<NameValuePair> buildParams(String query) {
        List<NameValuePair> result = new ArrayList<NameValuePair>();
        result.add(new BasicNameValuePair("query", query));
        result.add(new BasicNameValuePair("type", "triples"));
        result.add(new BasicNameValuePair("lang", "spo"));
        result.add(new BasicNameValuePair("format", "RDF/XML"));
        return result;
    }

    private String streamToString(InputStream is) throws IOException {
        if (is != null) {
            Writer writer = new StringWriter();
            char[] buffer = new char[1024];
            try {
                Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                int charsRead;
                while ((charsRead = reader.read(buffer)) != -1) {
                    writer.write(buffer, 0, charsRead);
                }
            } finally {
                is.close();
            }
            return writer.toString();
        } else {
            return "";
        }
    }
}
